package com.system.permissiondemo.service.impl;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.system.permissiondemo.dto.AclModuleLevelDTO;
import com.system.permissiondemo.dto.DeptLevelDTO;
import com.system.permissiondemo.entity.SysAclModule;
import com.system.permissiondemo.entity.SysDept;
import com.system.permissiondemo.mapper.SysAclModuleMapper;
import com.system.permissiondemo.mapper.SysDeptMapper;
import com.system.permissiondemo.service.SysTreeService;
import com.system.permissiondemo.util.LevelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
* @Description:    部门层级树设计
* @Author:         Joe
* @CreateDate:     2020/3/25 14:21
*/
@Service
public class SysTreeServiceImpl implements SysTreeService {

    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysAclModuleMapper sysAclModuleMapper;

    @Override
    public List<DeptLevelDTO> deptTree() {
        //取出基本数据
        List<SysDept> deptList = sysDeptMapper.getAllDept();

        //数据封装
        List<DeptLevelDTO> dtoList = Lists.newArrayList();
        for (SysDept dept : deptList){
            DeptLevelDTO dto = DeptLevelDTO.adapt(dept);
            dtoList.add(dto);
        }
        return deptListToTree(dtoList);
    }

    //组装
    @Override
    public List<DeptLevelDTO> deptListToTree(List<DeptLevelDTO> dtoList){
        if (CollectionUtils.isEmpty(dtoList)){
            return Lists.newArrayList();
        }
        // level -> [dept1, dept2, dept3, ...]
        Multimap<String, DeptLevelDTO> levelDeptmap = ArrayListMultimap.create();
        List<DeptLevelDTO> rootList = Lists.newArrayList();
        for (DeptLevelDTO dto:dtoList){
            levelDeptmap.put(dto.getLevel(),dto);
            if (LevelUtil.ROOT.equals(dto.getLevel())){
                rootList.add(dto);
            }
        }
        //按照seq从小到大排序
        Collections.sort(rootList, deptSeqComparator);
        //递归生成树
        transformDeptTree(rootList,LevelUtil.ROOT,levelDeptmap);
        return rootList;
    }

    //递归排序
    @Override
    public void transformDeptTree(List<DeptLevelDTO> deptLevelList,String level,Multimap<String, DeptLevelDTO> levelDeptMap){
        for (int i = 0; i < deptLevelList.size(); i++) {
            //遍历该层的每个元素
            DeptLevelDTO deptLevelDTO = deptLevelList.get(i);
            //处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level,deptLevelDTO.getId());

            //处理下一层数据
            List<DeptLevelDTO> tempDeptList = (List<DeptLevelDTO>)levelDeptMap.get(nextLevel);
            if (!CollectionUtils.isEmpty(tempDeptList)){
                //排序
                Collections.sort(tempDeptList,deptSeqComparator);
                //设置下一层部门
                deptLevelDTO.setDtoList(tempDeptList);
                //进入到下一层处理
                transformDeptTree(tempDeptList,nextLevel,levelDeptMap);
            }
        }
    }

    @Override
    public List<AclModuleLevelDTO> aclModuleTree() {
        //取出基本数据
        List<SysAclModule> aclModuleList = sysAclModuleMapper.getAllAclModule();

        //数据封装
        List<AclModuleLevelDTO> aclModuleLists = Lists.newArrayList();
        for (SysAclModule aclModule : aclModuleList){
            AclModuleLevelDTO dto = AclModuleLevelDTO.adapt(aclModule);
            aclModuleLists.add(dto);
        }
        return aclModuleListToTree(aclModuleLists);
    }

    @Override
    public List<AclModuleLevelDTO> aclModuleListToTree(List<AclModuleLevelDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)){
            return Lists.newArrayList();
        }
        // level -> [dept1, dept2, dept3, ...]
        Multimap<String, AclModuleLevelDTO> levelAclModuleMap = ArrayListMultimap.create();
        List<AclModuleLevelDTO> rootList = Lists.newArrayList();
        for (AclModuleLevelDTO dto:dtoList){
            levelAclModuleMap.put(dto.getLevel(),dto);
            if (LevelUtil.ROOT.equals(dto.getLevel())){
                rootList.add(dto);
            }
        }
        //按照seq从小到大排序
        Collections.sort(rootList, aclModuleSeqComparator);
        //递归生成树
        transformAclModuleTree(rootList,LevelUtil.ROOT,levelAclModuleMap);
        return rootList;
    }

    @Override
    public void transformAclModuleTree(List<AclModuleLevelDTO> aclModuleLevelList, String level, Multimap<String, AclModuleLevelDTO> levelAclModuleMap) {
        for (int i = 0; i < aclModuleLevelList.size(); i++) {
            //遍历该层的每个元素
            AclModuleLevelDTO aclModuleLevelDTO = aclModuleLevelList.get(i);
            //处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level,aclModuleLevelDTO.getId());

            //处理下一层数据
            List<AclModuleLevelDTO> tempAclModuleList = (List<AclModuleLevelDTO>)levelAclModuleMap.get(nextLevel);
            if (!CollectionUtils.isEmpty(tempAclModuleList)){
                //排序
                Collections.sort(tempAclModuleList,aclModuleSeqComparator);
                //设置下一层部门
                aclModuleLevelDTO.setDtoList(tempAclModuleList);
                //进入到下一层处理
                transformAclModuleTree(tempAclModuleList,nextLevel,levelAclModuleMap);
            }
        }
    }

    public Comparator<DeptLevelDTO> deptSeqComparator = new Comparator<DeptLevelDTO>(){
        public int compare(DeptLevelDTO o1,DeptLevelDTO o2){
            return o1.getSeq() - o2.getSeq();
        }
    };

    public Comparator<AclModuleLevelDTO> aclModuleSeqComparator = new Comparator<AclModuleLevelDTO>(){
        public int compare(AclModuleLevelDTO o1,AclModuleLevelDTO o2){
            return o1.getSeq() - o2.getSeq();
        }
    };
}
